import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import re
import concurrent.futures
from multi_Progress import perform_scan, update_progress
# import threading


def validate_input(ips, port_range, arguments):
    # 简单的验证示例
    ip_pattern = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
    port_pattern = re.compile(r"^\d+-\d+$")

    for ip in ips:
        if not ip_pattern.match(ip.strip()):
            raise ValueError("Invalid IP address")
        if not port_pattern.match(port_range):
            raise ValueError("Invalid port range")


def start_scan():
    # global scanning
    # scanning = True
    ip_addresses = ip_entry.get()
    port_range = port_entry.get()
    arguments = args_entry.get()

    try:
        # 输入的ip由逗号分隔
        ips = ip_addresses.split(",")
        # 检查合法性
        validate_input(ips, port_range, arguments)
        # 初始化ip列表
        ip_list = [ip.strip() for ip in ip_addresses.split(',')]
        # 给进程池分配最大容量
        progress['maximum'] = len(ip_list)
        # 清除先前的结果
        result_text.delete(1.0, tk.END)
        # 每个IP地址的扫描任务被分配到一个单独的线程中进行处理
        with concurrent.futures.ThreadPoolExecutor() as executor:
            # 开始多线程执行, future用于跟踪异步操作的结果
            futures = [executor.submit(perform_scan, ip, port_range, arguments) for ip in ip_list]
            # 开启进程池更新，update定期检查情况（100后的参数是函数名，随后接着的是需要传入的参数）
            root.after(100, update_progress, progress, futures, result_text, root)

    except Exception as e:
        messagebox.showerror("Input Error", str(e))


# 创建主窗口
root = tk.Tk()
root.title("Nmap Scanner")

# IP地址输入框
tk.Label(root, text="IP Address:").grid(row=0, column=0, padx=10, pady=10)
ip_entry = tk.Entry(root)
ip_entry.grid(row=0, column=1, padx=10, pady=10)

# 端口范围输入框
tk.Label(root, text="Port Range:").grid(row=1, column=0, padx=10, pady=10)
port_entry = tk.Entry(root)
port_entry.grid(row=1, column=1, padx=10, pady=10)

# 参数输入框
tk.Label(root, text="Nmap Arguments:").grid(row=2, column=0, padx=10, pady=10)
args_entry = tk.Entry(root)
args_entry.grid(row=2, column=1, padx=10, pady=10)

# 扫描按钮
scan_button = tk.Button(root, text="Start Scan", command=start_scan)
scan_button.grid(row=3, column=0, columnspan=2, pady=20)

# 结果显示区域
result_text = tk.Text(root, width=50, height=20)
result_text.grid(row=4, column=0, columnspan=2, padx=10, pady=10)

# 显示进度条
progress = ttk.Progressbar(root, orient='horizontal', length=200, mode='indeterminate')
progress.grid(row=5, column=0, columnspan=2, padx=10, pady=10)

# 运行主循环
root.mainloop()
